package com.unlcn.ils.wms.backend.service.sys.impl;

import cn.huiyunche.commons.domain.PageVo;
import cn.huiyunche.commons.exception.BusinessException;
import com.unlcn.ils.wms.backend.bo.sys.PermissionsBO;
import com.unlcn.ils.wms.backend.bo.sys.SysRoleBO;
import com.unlcn.ils.wms.backend.enums.DeleteFlagEnum;
import com.unlcn.ils.wms.backend.enums.StatusEnum;
import com.unlcn.ils.wms.backend.service.sys.PermissionsService;
import com.unlcn.ils.wms.backend.service.sys.SysRoleService;
import com.unlcn.ils.wms.base.mapper.extmapper.SysRoleCustomMapper;
import com.unlcn.ils.wms.base.mapper.extmapper.SysRolePermissionsCustomMapper;
import com.unlcn.ils.wms.base.mapper.sys.SysRoleMapper;
import com.unlcn.ils.wms.base.mapper.sys.SysRolePermissionsMapper;
import com.unlcn.ils.wms.base.model.sys.SysRole;
import com.unlcn.ils.wms.base.model.sys.SysRoleExample;
import com.unlcn.ils.wms.base.model.sys.SysRolePermissions;
import com.unlcn.ils.wms.base.model.sys.SysRolePermissionsExample;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @Auther linbao
 * @Date 2017-10-12
 */
@Service
public class SysRoleServiceImpl implements SysRoleService {

    private Logger LOGGER = LoggerFactory.getLogger(SysRoleServiceImpl.class);

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysRolePermissionsMapper sysRolePermissionsMapper;

    @Autowired
    private SysRolePermissionsCustomMapper sysRolePermissionsCustomMapper;

    @Autowired
    private SysRoleCustomMapper sysRoleCustomMapper;

    @Autowired
    private PermissionsService permissionsService;


    /**
     * 分页列表查询
     *
     * @param sysRoleBO
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, Object> listRole(SysRoleBO sysRoleBO) throws Exception {
        LOGGER.info("SysRoleServiceImpl.listRole roleBO: {}", sysRoleBO);
        checkRoleBO(sysRoleBO);
        Map<String, Object> resultMap = new HashMap<>();

        SysRoleExample roleExample = new SysRoleExample();
        roleExample.setLimitStart(sysRoleBO.getStartIndex());
        roleExample.setLimitEnd(sysRoleBO.getPageSize());
        SysRoleExample.Criteria criteria = roleExample.createCriteria();
        //角色编码
        if (StringUtils.isNotBlank(sysRoleBO.getCode())) {
            criteria.andCodeEqualTo(sysRoleBO.getCode());
        }
        //角色名称
        if (StringUtils.isNotBlank(sysRoleBO.getName())) {
            criteria.andNameEqualTo(sysRoleBO.getName());
        }
        //状态
        if (StringUtils.isNotBlank(sysRoleBO.getEnable())) {
            criteria.andEnableEqualTo(sysRoleBO.getEnable());
        }
        //默认非删除状态
        criteria.andIsDeletedEqualTo(DeleteFlagEnum.NORMAL.getValue());

        PageVo pageVo = new PageVo();
        pageVo.setPageNo(sysRoleBO.getPageNo());
        pageVo.setPageSize(sysRoleBO.getPageSize());
        pageVo.setTotalRecord(sysRoleMapper.countByExample(roleExample));

        resultMap.put("page", pageVo);
        resultMap.put("dataList", sysRoleMapper.selectByExample(roleExample));
        return resultMap;
    }

    /**
     * 新增
     *
     * @param sysRoleBO
     * @throws Exception
     */
    @Override
    public void addSysRole(SysRoleBO sysRoleBO) throws Exception {
        LOGGER.info("SysRoleServiceImpl.addSysRole roleBO: {}", sysRoleBO);
        checkRoleBO(sysRoleBO);
        //校验必填项
        checkRequired(sysRoleBO, false);
        //校验唯一性
        boolean resultBoolean = queryCheckRoleCodeUniqueue(sysRoleBO);
        if (!resultBoolean){
            throw new BusinessException("角色编码不唯一");
        }

        //TODO 保存角色信息
        SysRole addSysRole = new SysRole();
        BeanUtils.copyProperties(sysRoleBO, addSysRole);
        addSysRole.setIsDeleted(DeleteFlagEnum.NORMAL.getValue());
        addSysRole.setGmtModified(new Date());
        addSysRole.setGmtCreate(new Date());
        addSysRole.setCreatePerson(sysRoleBO.getCurrentUserName());
        ;
        addSysRole.setUpdatePerson(sysRoleBO.getCurrentUserName());
        sysRoleMapper.insertSelective(addSysRole);

        //TODO 保存角色中间关系
        saveRolePermess(sysRoleBO.getPermissionsIdList(), addSysRole.getId());
    }

    /**
     * 修改
     *
     * @param sysRoleBO
     * @throws Exception
     */
    @Override
    public void updateSysRole(SysRoleBO sysRoleBO) throws Exception {
        LOGGER.info("SysRoleServiceImpl.updateSysRole roleBO: {}", sysRoleBO);
        checkRoleBO(sysRoleBO);
        //校验必填项
        checkRequired(sysRoleBO, true);
        //校验唯一性
        boolean resultBoolean = queryCheckRoleCodeUniqueue(sysRoleBO);
        if (!resultBoolean){
            throw new BusinessException("角色编码不唯一");
        }
        SysRole sysRole = sysRoleMapper.selectByPrimaryKey(sysRoleBO.getId());
        if (Objects.equals(sysRole, null)) {
            throw new BusinessException("找不到对应的角色信息");
        }

        //TODO 删除角色权限中间关系数据
        SysRolePermissionsExample rolePermissionsExample = new SysRolePermissionsExample();
        rolePermissionsExample.createCriteria().andRoleIdEqualTo(sysRoleBO.getId());
        sysRolePermissionsMapper.deleteByExample(rolePermissionsExample);

        //TODO 保存角色信息
        SysRole updateSysRole = new SysRole();
        BeanUtils.copyProperties(sysRoleBO, updateSysRole);
        updateSysRole.setGmtModified(new Date());
        updateSysRole.setUpdatePerson(sysRoleBO.getCurrentUserName());
        sysRoleMapper.updateByPrimaryKeySelective(updateSysRole);

        //TODO 保存角色中间关系
        saveRolePermess(sysRoleBO.getPermissionsIdList(), updateSysRole.getId());
    }

    /**
     * 删除
     *
     * @param sysRoleBO
     * @throws Exception
     */
    @Override
    public void deleteSysRole(SysRoleBO sysRoleBO) throws Exception {
        LOGGER.info("SysRoleServiceImpl.deleteSysRole roleBO: {}", sysRoleBO);
        checkRoleBO(sysRoleBO);

        if (CollectionUtils.isEmpty(sysRoleBO.getRoleIdList())) {
            throw new BusinessException("请选择角色");
        }
        //删除角色
        SysRole sysRole = new SysRole();
        sysRole.setIsDeleted(DeleteFlagEnum.DELETED.getValue());

        SysRoleExample roleExample = new SysRoleExample();
        roleExample.createCriteria().andIdIn(sysRoleBO.getRoleIdList());
        sysRoleMapper.updateByExampleSelective(sysRole, roleExample);

        //删除角色权限关系
        SysRolePermissionsExample rolePermissionsExample = new SysRolePermissionsExample();
        rolePermissionsExample.createCriteria().andRoleIdIn(sysRoleBO.getRoleIdList());
        sysRolePermissionsMapper.deleteByExample(rolePermissionsExample);
    }

    /**
     * 根据用户ID查询对应的角色
     *
     * @param sysRoleBO
     * @return
     * @throws Exception
     */
    @Override
    public List<SysRole> listRoleByUserId(SysRoleBO sysRoleBO) throws Exception {
        LOGGER.info("SysRoleServiceImpl.listRoleByUserId roleBO: {}", sysRoleBO);
        return sysRoleCustomMapper.selectByUserId(sysRoleBO.getUserId(), StatusEnum.RIGHT.getValue());
    }

    /**
     * 校验策略代码是否唯一
     *
     * @param sysRoleBO
     * @return
     * @throws Exception
     */
    @Override
    public boolean queryCheckRoleCodeUniqueue(SysRoleBO sysRoleBO) throws Exception {
        LOGGER.info("SysRoleServiceImpl.checkRoleCodeUniqueue roleBO: {}", sysRoleBO);
        checkRoleBO(sysRoleBO);
        boolean resultBoolean = false;
        if (StringUtils.isNotBlank(sysRoleBO.getCode())) {
            SysRoleExample roleExample = new SysRoleExample();
            SysRoleExample.Criteria criteria = roleExample.createCriteria();
            criteria.andCodeEqualTo(sysRoleBO.getCode());
            criteria.andIsDeletedEqualTo(DeleteFlagEnum.NORMAL.getValue());
            if (!Objects.equals(sysRoleBO.getId(), null)) {
                criteria.andIdNotEqualTo(sysRoleBO.getId());
            }
            int resultCount = sysRoleMapper.countByExample(roleExample);
            if (resultCount <= 0) {
                resultBoolean = true;
            }
        }
        return resultBoolean;
    }

    /**
     * 根据角色获取权限
     *
     * @param sysRoleBO
     * @return
     * @throws Exception
     */
    @Override
    public List<PermissionsBO> listPermissByRoleId(SysRoleBO sysRoleBO) throws Exception {
        LOGGER.info("SysRoleServiceImpl.listPermissByRoleId roleBO: {}", sysRoleBO);
        checkRoleBO(sysRoleBO);
        if (!Objects.equals(sysRoleBO.getId(), null)){
            return permissionsService.findByRoleId(sysRoleBO.getId(), null);
        }
        return null;
    }

    /**
     * 根据userId获取对应的角色
     *
     * @param userId
     * @return
     * @throws Exception
     */
    @Override
    public List<SysRole> getRoleListByUserId(Integer userId) throws Exception {
        return sysRoleCustomMapper.selectByUserId(userId, StatusEnum.RIGHT.getValue());
    }

    /**
     * 保存角色权限中间关系
     *
     * @param permissionIdList
     * @param roleId
     */
    private void saveRolePermess(List<Integer> permissionIdList, Integer roleId) {
        if (CollectionUtils.isNotEmpty(permissionIdList)) {
            List<SysRolePermissions> rolePermissionList = new ArrayList<>();
            SysRolePermissions rolePermissions = null;
            for (Integer permissionsId : permissionIdList) {
                if (!Objects.equals(permissionsId, null)) {
                    rolePermissions = new SysRolePermissions();
                    rolePermissions.setRoleId(roleId);
                    rolePermissions.setPermissionsId(permissionsId);
                    rolePermissionList.add(rolePermissions);
                }
            }
            if (CollectionUtils.isNotEmpty(rolePermissionList)) {

                sysRolePermissionsCustomMapper.insertBatch(rolePermissionList);
            }
        }
    }


    /**
     * 参数校验
     *
     * @param sysRoleBO
     */
    private void checkRoleBO(SysRoleBO sysRoleBO) {
        if (Objects.equals(sysRoleBO, null)) {
            throw new BusinessException("参数为空");
        }
    }

    /**
     * 校验必填项
     *
     * @param sysRoleBO
     */
    private void checkRequired(SysRoleBO sysRoleBO, boolean isUpdate) {

        if (StringUtils.isBlank(sysRoleBO.getCode())) {
            throw new BusinessException("角色编码不能为空");
        }
        if (StringUtils.isBlank(sysRoleBO.getName())) {
            throw new BusinessException("角色名字不能为空");
        }
        if (StringUtils.isBlank(sysRoleBO.getEnable())) {
            throw new BusinessException("角色状态不能为空");
        }
        if (isUpdate) {
            if (Objects.equals(sysRoleBO.getId(), null)) {
                throw new BusinessException("请选择对应的角色");
            }
        }
    }
}
